<?php
namespace App\ModelStatistic;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Input;

/**
 * 维度 角色
 * 每日 新增用户付费情况
 */
class PayRetainPlayer extends  Model{

    const RETAIN_STEP = 86400;
    const conn = 'mysql_statistic';
    const RETAIN_DAYS = 30;
    
	public function paginate()
    {
        $qdCond = StatisticCommon::remainChartDate(self::get_reg_date());
        $table = 'pay_retain_player';
        $rw = \DB::connection($this->selectdb())->table($table);
        $rw = $rw->where('area', intval($area = Input::get('cp_area') ?: Input::get('area')));
        // 自定义时间查询
        if (isset($qdCond['start'])) {
            
            $rw->whereRaw("reg_date >= '{$qdCond['start']}'");
        }

        if (isset($qdCond['end'])) {
            
            $rw->whereRaw("reg_date <= '{$qdCond['end']}'");
        }
        //$result = \DB::connection($this->selectdb())->select($sql);

        $rw->orderBy('reg_date', 'DESC');
        $list = $rw->get()->toArray();

        $rtn = [];
        foreach ( $list as $obj) {
            $day = ($obj->com_date - $obj->reg_date + self::RETAIN_STEP) / self::RETAIN_STEP;
            $day = 'day'. $day;
            $game_amount = round($obj->amount_game/100, 2);
            $rtn[$obj->reg_date][$day] = ' <p> '. abs($obj->pay_count) .'</p><p>' . $game_amount . '</p>';
            if ($obj->pay_count < 0 ) {
                $rtn[$obj->reg_date][$day] = '<span style="color:red;">'.$rtn[$obj->reg_date][$day].'</span>';
            }
            // 汇总金额
            $rtn[$obj->reg_date]['total_amount'] += $game_amount;
            $rtn[$obj->reg_date]['avg_amount'] = round($rtn[$obj->reg_date]['total_amount'] / $obj->reg_num,2);
            // $rtn[$obj->reg_date][date("Y-m-d", $obj->com_date)] = $obj;
            $rtn[$obj->reg_date]['reg_date'] = $obj->reg_date;
            $rtn[$obj->reg_date]['reg_num'] = $obj->reg_num;
            $rtn[$obj->reg_date]['amount_'.$day] = $game_amount;
            $rtn[$obj->reg_date]['count_'.$day] = intval($obj->pay_count);
        }
        if (!empty($rtn) ) {
            $item_total = [];
            $space = '&nbsp;&nbsp;&nbsp;&nbsp;';
            foreach ($rtn as $date => $stobj) {
                $item_total['reg_num'] += $stobj['reg_num'];
                $item_total['total_amount'] += $stobj['total_amount'];

                // 计算各个导量 第N日付费情况
                for ($i =1; $i<=30; $i++) {
                    $fld = 'day' . $i;
                    $amount_fld = 'amount_' . $fld;
                    $item_total[$fld] += intval($stobj[$amount_fld]);
                    $rtn[$date][$fld] = $stobj['count_'.$fld] == 0 ?0:'<p>'.$stobj['count_'.$fld]. '
                    
                    '.$space . round( $stobj[$amount_fld]/($stobj['count_'.$fld] ?: 1), 2) . '</p>
                   
                    <p> '.round(100*$stobj[$amount_fld]/$stobj['total_amount']).'% '. $space . $stobj[$amount_fld] . $space. round( $stobj[$amount_fld]/($stobj['reg_num'] ?: 1), 2)  . '</p>'
                    ;
                    //  <p> ' . round($stobj[$amount_fld]/$stobj['reg_num'],2) .'</p>
                }
            }
            for ($i =1; $i<=30; $i++) {
                $fld = 'day' . $i;
                if ($item_total['total_amount']) {
                    $item_total[$fld] = round(100 *$item_total[$fld]/$item_total['total_amount'], 2) .'%('. $item_total[$fld] . ')';
                }
            }

            $item_total['avg_amount'] = round($item_total['total_amount'] / $item_total['reg_num'], 2);
            $item_total['reg_date'] = 'TOTAL';
            $rtn['total'] = $item_total;
        }

    
        $total = count($rtn);
        $list = static::hydrate($rtn);

        $paginator = new LengthAwarePaginator($rtn, $total, 100);

        $paginator->setPath(url()->current());

        return $paginator;
    }
    public function selectdb(){
        
        return self::conn;
    }

    public function getConnectionName(){
        
        return $this->selectdb();
    }  
    // 数据生产
    public function generate()
    {
        $qdCond = StatisticCommon::remainChartDate(self::get_reg_date());
        $area = Input::get('cp_area') ?: Input::get('area');
        \App\Models\Area::RemoteBgsiSelectByArea($area);

        $start = $qdCond['start'];
        $end = $qdCond['end'];

        $start = strtotime(date("Y-m-d", $start)) + self::RETAIN_STEP;
        $end = strtotime(date("Y-m-d", $end))+ self::RETAIN_STEP;
        $tomarrow = strtotime(date("Y-m-d")) + self::RETAIN_STEP;
        if ($end > $tomarrow) {
            $end = $tomarrow;
        }
        $end_count = ($end - $start)/self::RETAIN_STEP;
        // 最多做100条统计
        ($end_count > 100) && $end_count = 100;
        $now = time();
        $cur_int = strtotime(date("Y-m-d", $now));
        
        \Log::info('[CHARGE-RETAIN-ROLE][START]', ['start'=>date("Y-m-d", $start), 'end'=>date("Y-m-d", $end)]);
        $resource_data = $this->get_retain_data($area, $start, $end);
        for ($step =0; $step < $end_count; $step++) {
            $use_int = $start + self::RETAIN_STEP * $step;

            $player_ids = self::GetPlayersByRetain($area, $use_int);
            $reg_num = count($player_ids);
            if (empty($player_ids)) {
                continue;
            }

            $insert_data = []; // 有效记录
            for ($day = 0; $day<30; $day++) {
                $compare_int = $use_int + $day * self::RETAIN_STEP;
                if ($compare_int >= $tomarrow) {
                    continue;
                }
                $obj = null;
                if (isset($resource_data[$use_int]) && isset($resource_data[$use_int][$compare_int]) ) {
                    $obj = $resource_data[$use_int][$compare_int];

                    if ($obj->pay_count > 0 ) {
                        continue;
                    }
                }

                $order = self::order_statistic($player_ids, $compare_int);

                if (empty( $order)) {
                    continue;
                }
                
                // 先删除 再插入
                if ($obj && $obj->pay_count < 0) {
                    \Log::debug("[DELETE-CHARGE-ROLE]", [$use_int, $compare_int]);
                    $this->deleteBy($use_int, $compare_int);
                }

                if ($compare_int == $cur_int ) {
                    $order->total *= -1;
                }

                $insert_data[] = [
                    'area' => $area,
                    'reg_date' => $use_int,
                    'reg_num'   => $reg_num,
                    'com_date' => $compare_int,
                    'pay_count' => $order->total,
                    'amount_game' => $order->amount_game,
                    'amount'    => $order->amount,
                    'add_time'  => $now,
                ];
            }

            if ($insert_data ) {
                \DB::connection(self::conn)->table('pay_retain_player')->insert($insert_data);
            }
        }
    }

    public function get_retain_data($area, $start, $end) {
        $list = \DB::connection(self::conn)->table('pay_retain_player')->select('*')->where('reg_date', ">=", $start)->where('reg_date', "<=", $end)->where('area', $area)->get()->toArray();
        $ret_arr = [];
        foreach ($list as $obj) {
            $ret_arr[$obj->reg_date][$obj->com_date] = $obj;
        }
        return $ret_arr;
    }

    // 获取留存比较日的 注册用户
    public static function GetPlayersByRetain( $area, $retain_time)
    {
        $start = date("Y-m-d 00:00:00", $retain_time);
        $end = date("Y-m-d 23:59:59", $retain_time);


        $data = \DB::connection('remote_bgsi')->table('user_login')->select('player_id')->whereBetween('reg_time',[$start, $end])->groupBy("player_id");
        
        $data = $data->get();
        
        $player_ids_item = [];
        foreach($data as $obj){
            $player_ids_item[] = $obj->player_id;
        }
        
        \Log::debug(__METHOD__, ['END', $start, count($player_ids_item) ]);
        return $player_ids_item;
    }

    // 统计当日订单统计值
    public static function order_statistic($player_ids, $retain_time) {
        $end_time = $retain_time + self::RETAIN_STEP;
        $rw = \DB::connection('mysql_bgac')->table('platsdk_order')->select(\DB::raw('count(1) as total'), \DB::raw('sum(OrderMoney) as amount'), \DB::raw('sum(cp_rmb) as amount_game'))
        ->whereIn("cp_player_id", $player_ids)->where('created_time', ">=", $retain_time)->where('created_time', '<=', $end_time)->where('OrderSerial', '<>', '')->where('deleted_at',0);
        // ->groupBy('cp_player_id');

        $data = $rw->first();

        $sub_q = \DB::connection('mysql_bgac')->table('platsdk_order')->selectRaw('cp_player_id')
        ->whereIn("cp_player_id", $player_ids)->where('created_time', ">=", $retain_time)->where('created_time', '<=', $end_time)->where('OrderSerial', '<>', '')
        ->where("deleted_at", 0)
        ->groupBy('cp_player_id');
        
        $data_count = \DB::connection('mysql_bgac')->table(\DB::raw("({$sub_q->toSql()}) as sub"))
        ->mergeBindings($sub_q)->count();
        
        if ($data_count && $data) {
            $data->total = $data_count;
        }
        if ( !$data->total) {
            return null;
        }
        \Log::debug('[CHARGE-RETAIN-ROLE][statistic]', [date('Y-m-d', $retain_time),$data_count,  count($player_ids)]);
        return $data;
    }

    public function deleteBy($reg_date, $com_date) {
        \DB::connection(self::conn)->table('pay_retain_player')->where('reg_date', $reg_date)->where('com_date', $com_date)->delete();
    }

    public static function get_reg_date()
    {
        $com_date = Request::get('reg_date');
        if (!$com_date || !$com_date['start']) {
            $com_date = Request::get('retain_time');
            
            if (!$com_date) {
                $com_date['start'] = date('Y-m-d', strtotime('-7 days'));
                $com_date['end'] = date('Y-m-d', time());
            }
        }

        return $com_date;
    }
}